package com.inputabc.ct.v1.ui;


import com.inputabc.EzGUIFramework.listener.ListenerBinder;
import com.inputabc.EzGUIFramework.util.EzGUI;
import com.inputabc.EzGUIFramework.util.alias.Ez;
import com.inputabc.ct.v1.context.Components;
import com.inputabc.ct.v1.context.ComponentsBuilder;
import com.inputabc.ct.v1.context.ContextParams;
import com.inputabc.ct.v1.setting.KeySetting;
import com.inputabc.ct.v1.setting.SettingContext;
import com.inputabc.ct.v1.setting.TextBoxSetting;
import com.inputabc.ct.v1.setting.TranslateSetting;
import com.inputabc.ct.v1.ui.action.TextBoxAction;
import com.inputabc.ct.v1.ui.listener.TextBoxPopupMeunListenerHandler;
import com.inputabc.ct.v1.util.BaiduUtils;
import com.inputabc.ct.v1.util.GoogleUtils;
import com.inputabc.ct.v1.util.YoudaoUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.SystemUtils;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.Timer;
import java.util.*;

public class TextBox extends JPanel {
    private Components textBoxComponents = ComponentsBuilder.getComponentsContext().get(TextBox.class);
    private JFrame jf = (JFrame) textBoxComponents.get("textBoxFrame");
    private JPanel jp = (JPanel) textBoxComponents.get("textBoxPanel");
    private JTextArea ta = (JTextArea) textBoxComponents.get("textBoxTextArea");
    private JScrollPane jsp = (JScrollPane) textBoxComponents.get("textBoxScrollPane");
    private JPopupMenu jpm = (JPopupMenu) textBoxComponents.get("textBoxPopupMenu");
    private JMenuItem closeMi = (JMenuItem) textBoxComponents.get("textBoxCloseMenuItem");
    private JMenuItem selectAllMi = (JMenuItem) textBoxComponents.get("textBoxSelectAllMenuItem");
    private JMenuItem selectAllAndCopyMi = (JMenuItem) textBoxComponents.get("textBoxSelectAllAndCopyMenuItem");
    private JMenuItem copyMi = (JMenuItem) textBoxComponents.get("textBoxCopyMenuItem");
    private JMenuItem moveMi = (JMenuItem) textBoxComponents.get("textBoxMoveMenuItem");
    private JMenu textBoxTranslationMenu = (JMenu) textBoxComponents.get("textBoxTranslationMenu");
    private JMenuItem textBoxTranslationMenuEN2CN = (JMenuItem) textBoxComponents.get("textBoxTranslationMenuEN2CN");
    private JMenuItem textBoxTranslationMenuJA2CN = (JMenuItem) textBoxComponents.get("textBoxTranslationMenuJA2CN");
    private JMenuItem textBoxTranslationMenuKR2CN = (JMenuItem) textBoxComponents.get("textBoxTranslationMenuKR2CN");
    private JMenuItem textBoxTranslationMenuCN2EN = (JMenuItem) textBoxComponents.get("textBoxTranslationMenuCN2EN");
    private JMenuItem textBoxTranslationMenuCN2JA = (JMenuItem) textBoxComponents.get("textBoxTranslationMenuCN2JA");
    private JMenuItem textBoxTranslationMenuCN2KR = (JMenuItem) textBoxComponents.get("textBoxTranslationMenuCN2KR");
    private JMenuItem textBoxTranslationMenuAUTO2CN = (JMenuItem) textBoxComponents.get("textBoxTranslationMenuAUTO2CN");
    private JMenuItem textBoxTranslationMenuAUTO2EN = (JMenuItem) textBoxComponents.get("textBoxTranslationMenuAUTO2EN");
    private JMenuItem textBoxTranslationMenuAUTO2JA = (JMenuItem) textBoxComponents.get("textBoxTranslationMenuAUTO2JA");
    private JMenuItem textBoxTranslationMenuAUTO2KR = (JMenuItem) textBoxComponents.get("textBoxTranslationMenuAUTO2KR");
    private JMenuItem textBoxRefreshMenu = (JMenuItem) textBoxComponents.get("textBoxRefreshMenu");
    private JMenu textBoxTranslationEngineMenu = (JMenu) textBoxComponents.get("textBoxTranslationEngineMenu");
    private JMenuItem textBoxTranslationEngineMenuYoudao = (JMenuItem) textBoxComponents.get("textBoxTranslationEngineMenuYoudao");
    private JMenuItem textBoxTranslationEngineMenuBaidu = (JMenuItem) textBoxComponents.get("textBoxTranslationEngineMenuBaidu");
    private JMenuItem textBoxTranslationEngineMenuGoogle = (JMenuItem) textBoxComponents.get("textBoxTranslationEngineMenuGoogle");
    private JMenuItem textBoxTranslationEngineMenuDeepSeek; // 添加DeepSeek翻译引擎菜单项
    private JMenu textBoxSpeckMenu = (JMenu) textBoxComponents.get("textBoxSpeckMenu");
    private JMenuItem textBoxSpeckMenuBeforeTranslate = (JMenuItem) textBoxComponents.get("textBoxSpeckMenuBeforeTranslate");
    private JMenu textBoxSpeckMenuAfterTranslatedMenu = (JMenu) textBoxComponents.get("textBoxSpeckMenuAfterTranslatedMenu");
    private JMenuItem textBoxSpeckMenuAfterTranslateMenuAll = (JMenuItem) textBoxComponents.get("textBoxSpeckMenuAfterTranslateMenuAll");
    private JMenuItem textBoxSpeckMenuAfterTranslateMenuSelected = (JMenuItem) textBoxComponents.get("textBoxSpeckMenuAfterTranslateMenuSelected");
    private JMenuItem textBoxKeyMenuItem = (JMenuItem) textBoxComponents.get("textBoxKeyMenuItem");
    private JMenu textBoxHelpMenu = (JMenu) textBoxComponents.get("textBoxHelpMenu");
    private JMenuItem textBoxHelpTopicMenuItem = (JMenuItem) textBoxComponents.get("textBoxHelpTopicMenuItem");
    private JMenuItem textBoxAboutMenuItem = (JMenuItem) textBoxComponents.get("textBoxAboutMenuItem");
    private JMenuItem textBoxMinimumMenuItem = (JMenuItem) textBoxComponents.get("textBoxMinimumMenuItem");
    private JMenuItem textBoxOpenInputBoxMenuItem = (JMenuItem) textBoxComponents.get("textBoxOpenInputBoxMenuItem");
    private JMenuItem textBoxClearMenuItem = (JMenuItem) textBoxComponents.get("textBoxClearMenuItem");

    // 新增设置菜单和历史记录菜单
    private JMenuItem textBoxSettingsMenuItem;
    private JMenuItem textBoxHistoryMenuItem;

    // 新增帮助菜单和关于菜单项
    private JMenuItem textBoxHelpMenuItem;

    // 新增外观菜单和菜单项
    private JMenu appearanceMenu;
    private JMenuItem backgroundImageItem;
    private JMenuItem toggleBackgroundImageItem;
    private JMenuItem fontMenuItem;
    private JMenuItem textColorMenuItem;
    private JMenuItem backgroundColorMenuItem;
    private JMenuItem opacityMenuItem;

    // 翻译历史记录对话框
    private TranslationHistoryDialog historyDialog;

    // 用于记录当前选择的翻译方向和引擎
    private JMenuItem currentTranslationDirectionMenuItem;
    private JMenuItem currentTranslationEngineMenuItem;

    boolean left, right, up, down, add, subtract;
    private TextBoxAction textBoxAction = new TextBoxAction();
    private ListenerBinder resizeBoxListenerBinder = Ez.getListenerBinder(textBoxAction);
    public boolean resizingBox;
    private String resizeType;
    private TextBoxSetting textBoxSetting = SettingContext.textBoxSetting;
    private TranslateSetting translateSetting = SettingContext.translateSetting;
    private KeySetting keySetting = SettingContext.keySetting;
    private Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    private final static String SETTING_CONF = "settings.conf";

    // 配置文件属性键
    private final static String BACKGROUND_IMAGE_PATH_KEY = "textbox.background.image.path";
    private final static String BACKGROUND_IMAGE_ENABLED_KEY = "textbox.background.image.enabled";

    // 背景图片相关
    private Image backgroundImage;
    private boolean useBackgroundImage = false;

    public TextBox() throws IOException {
        ContextParams.contextParam.put("textBox", this);
        jsp.setViewportView(ta);
        init();
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                Float opacity = textBoxSetting.getOpacity();
                safelySetOpacity(jf, opacity);
            }
        },0,15);
    }

    private void init() throws IOException {
        // 首先设置窗口为无装饰模式
        jf.setUndecorated(true);

        // 设置窗体大小
        setFrameSize();
        jf.setMinimumSize(new Dimension(213, 73));
        jf.setMaximumSize(screenSize);
        setFrameLocation();

        // 先加载背景图片设置
        loadBackgroundImage();

        // 创建支持背景图片的自定义面板并存储为全局变量
        jp = new BackgroundPanel();
        textBoxComponents.put("textBoxPanel", jp); // 确保组件上下文中的引用也更新
        jp.setLayout(new BorderLayout());
        jp.add(jsp);

        jf.setContentPane(jp);

        jsp.setAutoscrolls(true);
        // 设置文本区域的背景色
        setScrollPaneBackground();
        // 设置文本区域的前景色
        setTextAreaForeground();
        // 设置字体
        setFont();
        //设置默认显示的文字
        String helpMeText = IOUtils.toString(ContextParams.class.getResource("/icon/help.me"), "UTF-8");
        ta.setText(helpMeText);

        ta.setLineWrap(true);
        ta.setWrapStyleWord(true);
        ta.setEditable(false);
        ta.setOpaque(false);
        ta.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));

        // 透明度设置将在loadAppearanceSettings()方法中统一加载
        // 这里不再单独加载透明度设置，避免重复加载或设置被覆盖

        textBoxTranslationMenu.setText("互译");
        jpm.add(textBoxTranslationMenu);
        textBoxTranslationEngineMenu.setText("翻译引擎");
        jpm.add(textBoxTranslationEngineMenu);
        textBoxSpeckMenu.setText("朗读");
        jpm.add(textBoxSpeckMenu);
        copyMi.setText("复制");
        jpm.add(copyMi);
        selectAllMi.setText("全选");
        jpm.add(selectAllMi);
        selectAllAndCopyMi.setText("全选并复制");
        jpm.add(selectAllAndCopyMi);
        moveMi.setText("移动");
        //jpm.add(moveMi);
        textBoxRefreshMenu.setText("刷新");
        jpm.add(textBoxRefreshMenu);
        textBoxClearMenuItem.setText("清空");
        jpm.add(textBoxClearMenuItem);
        textBoxOpenInputBoxMenuItem.setText("打开输入框");
        //  jpm.add(textBoxOpenInputBoxMenuItem);
        textBoxKeyMenuItem.setText("设置API密钥");
        jpm.add(textBoxKeyMenuItem);

        // 添加设置菜单项
        textBoxSettingsMenuItem = new JMenuItem("设置");
        jpm.add(textBoxSettingsMenuItem);

        // 添加历史记录菜单项
        textBoxHistoryMenuItem = new JMenuItem("历史记录");
        jpm.add(textBoxHistoryMenuItem);

        // 添加帮助菜单项
        textBoxHelpMenuItem = new JMenuItem("帮助");
        jpm.add(textBoxHelpMenuItem);

        // 设置关于菜单项文本并添加到弹出菜单
        textBoxAboutMenuItem.setText("关于");
        jpm.add(textBoxAboutMenuItem);

        // 添加外观菜单和菜单项
        appearanceMenu = new JMenu("外观");
        appearanceMenu.setName("appearanceMenu");
        //   jpm.add(appearanceMenu);

        backgroundImageItem = new JMenuItem("背景图片");
        backgroundImageItem.setName("backgroundImageItem");
        appearanceMenu.add(backgroundImageItem);

        // 添加启用/禁用背景图片菜单项
        toggleBackgroundImageItem = new JMenuItem("禁用背景图片");
        toggleBackgroundImageItem.setName("toggleBackgroundImageItem");
        appearanceMenu.add(toggleBackgroundImageItem);

        // 添加字体菜单项
        fontMenuItem = new JMenuItem("字体");
        fontMenuItem.setName("fontMenuItem");
        appearanceMenu.add(fontMenuItem);

        // 添加文字颜色菜单项
        textColorMenuItem = new JMenuItem("文字颜色");
        textColorMenuItem.setName("textColorMenuItem");
        appearanceMenu.add(textColorMenuItem);

        // 添加背景颜色菜单项
        backgroundColorMenuItem = new JMenuItem("背景颜色");
        backgroundColorMenuItem.setName("backgroundColorMenuItem");
        appearanceMenu.add(backgroundColorMenuItem);

        // 添加透明度菜单项
        opacityMenuItem = new JMenuItem("透明度");
        opacityMenuItem.setName("opacityMenuItem");
        appearanceMenu.add(opacityMenuItem);

        textBoxMinimumMenuItem.setText("最小化");
        if (SystemUtils.IS_OS_LINUX || SystemUtils.IS_OS_MAC || SystemUtils.IS_OS_UNIX) {
            jpm.add(textBoxMinimumMenuItem);
        }
        closeMi.setText("关闭");
        jpm.add(closeMi);

        textBoxTranslationMenuEN2CN.setText("英->中");
        textBoxTranslationMenu.add(textBoxTranslationMenuEN2CN);
        textBoxTranslationMenuJA2CN.setText("日->中");
        textBoxTranslationMenu.add(textBoxTranslationMenuJA2CN);
        textBoxTranslationMenuKR2CN.setText("韩->中");
        textBoxTranslationMenu.add(textBoxTranslationMenuKR2CN);
        textBoxTranslationMenu.addSeparator();
        textBoxTranslationMenuCN2EN.setText("中->英");
        textBoxTranslationMenu.add(textBoxTranslationMenuCN2EN);
        textBoxTranslationMenuCN2JA.setText("中->日");
        textBoxTranslationMenu.add(textBoxTranslationMenuCN2JA);
        textBoxTranslationMenuCN2KR.setText("中->韩");
        textBoxTranslationMenu.add(textBoxTranslationMenuCN2KR);
        textBoxTranslationMenu.addSeparator();
        textBoxTranslationMenuAUTO2CN.setText("自动检测->中");
        textBoxTranslationMenu.add(textBoxTranslationMenuAUTO2CN);
        textBoxTranslationMenuAUTO2EN.setText("自动检测->英");
        textBoxTranslationMenu.add(textBoxTranslationMenuAUTO2EN);
        textBoxTranslationMenuAUTO2JA.setText("自动检测->日");
        textBoxTranslationMenu.add(textBoxTranslationMenuAUTO2JA);
        textBoxTranslationMenuAUTO2KR.setText("自动检测->韩");
        textBoxTranslationMenu.add(textBoxTranslationMenuAUTO2KR);

        // 翻译引擎菜单
        textBoxTranslationEngineMenuYoudao.setText("有道");
        textBoxTranslationEngineMenu.add(textBoxTranslationEngineMenuYoudao);
        textBoxTranslationEngineMenuBaidu.setText("百度");
        textBoxTranslationEngineMenu.add(textBoxTranslationEngineMenuBaidu);
        textBoxTranslationEngineMenuGoogle.setText("谷歌");
        textBoxTranslationEngineMenu.add(textBoxTranslationEngineMenuGoogle);

        // 添加DeepSeek翻译引擎菜单项
        textBoxTranslationEngineMenuDeepSeek = new JMenuItem("DeepSeek AI (免费)");
        textBoxTranslationEngineMenuDeepSeek.setName("textBoxTranslationEngineMenuDeepSeek");
        textBoxTranslationEngineMenu.add(textBoxTranslationEngineMenuDeepSeek);

        // 朗读菜单
        textBoxSpeckMenuBeforeTranslate.setText("翻译前");
        textBoxSpeckMenu.add(textBoxSpeckMenuBeforeTranslate);
        textBoxSpeckMenuAfterTranslatedMenu.setText("翻译后");
        textBoxSpeckMenu.add(textBoxSpeckMenuAfterTranslatedMenu);
        textBoxSpeckMenuAfterTranslateMenuAll.setText("全部");
        textBoxSpeckMenuAfterTranslatedMenu.add(textBoxSpeckMenuAfterTranslateMenuAll);
        textBoxSpeckMenuAfterTranslateMenuSelected.setText("已选择的");
        textBoxSpeckMenuAfterTranslatedMenu.add(textBoxSpeckMenuAfterTranslateMenuSelected);

        // 帮助菜单
        textBoxHelpTopicMenuItem.setText("使用指南");
        textBoxHelpMenu.add(textBoxHelpTopicMenuItem);

        // 加载外观设置
        loadAppearanceSettings();

        // 设置边框样式
        setBorderStyle();

        // 设置弹出菜单 - 使用原生Swing方式替代EzGUI
        ta.setComponentPopupMenu(jpm);
        // 为了兼容性，再添加鼠标事件监听器显式处理右键
        ta.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    jpm.show(e.getComponent(), e.getX(), e.getY());
                }
            }
            
            @Override
            public void mouseReleased(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    jpm.show(e.getComponent(), e.getX(), e.getY());
                }
            }
        });

        // 设置窗体
        jf.setAlwaysOnTop(true);

        // 安全地设置图标
        try {
            java.net.URL iconURL = ContextParams.class.getResource("/icon/title.png");
            if (iconURL != null) {
                ImageIcon icon = new ImageIcon(Toolkit.getDefaultToolkit().getImage(iconURL));
                jf.setIconImage(icon.getImage());
            } else {
                System.err.println("警告: 找不到图标文件 '/icon/title.png'");
            }
        } catch (Exception e) {
            System.err.println("设置图标时出错: " + e.getMessage());
            e.printStackTrace();
        }

        // 安全地设置菜单选中图标
        Icon checkIcon = null;
        try {
            java.net.URL checkIconURL = ContextParams.class.getResource("/icon/checkmark.png");
            if (checkIconURL != null) {
                checkIcon = new ImageIcon(checkIconURL);
            }
        } catch (Exception e) {
            System.err.println("加载勾选图标时出错: " + e.getMessage());
        }

        // 如果没有找到图标文件，创建一个简单的勾选图标
        if (checkIcon == null) {
            checkIcon = new ImageIcon() {
                @Override
                public void paintIcon(Component c, Graphics g, int x, int y) {
                    Graphics2D g2d = (Graphics2D) g.create();
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                    g2d.setColor(Color.GREEN.darker());
                    int[] xPoints = {x, x + 3, x + 9};
                    int[] yPoints = {y + 4, y + 7, y};
                    g2d.drawPolyline(xPoints, yPoints, 3);
                    g2d.dispose();
                }

                @Override
                public int getIconWidth() {
                    return 12;
                }

                @Override
                public int getIconHeight() {
                    return 12;
                }
            };
        }
        ContextParams.contextParam.put("menuIcon", checkIcon);

        // 读取设置，确定默认翻译方向和引擎
        loadTranslationSettings();

        // 添加事件
        event();

        // 显示窗体
        jf.setVisible(true);
    }

    /**
     * 设置边框样式
     */
    private void setBorderStyle() {
        try {
            Properties p = new Properties();
            File file = new File(SETTING_CONF);
            if (file.exists()) {
                p.load(file.toURI().toURL().openStream());
                String borderStyleStr = p.getProperty("textbox.border.style", "0");
                int borderStyle = Integer.parseInt(borderStyleStr);

                // 读取当前配置的背景颜色
                String bgColorV = p.getProperty("textbox.background.color", "0,0,0");
                Color backgroundColor = Color.BLACK; // 默认黑色

                try {
                    String[] colorSplits = bgColorV.split(",");
                    if (colorSplits.length == 3) {
                        int red = Integer.parseInt(colorSplits[0]);
                        int green = Integer.parseInt(colorSplits[1]);
                        int blue = Integer.parseInt(colorSplits[2]);
                        backgroundColor = new Color(red, green, blue);
                    }
                } catch (Exception e) {
                    System.err.println("解析背景颜色出错: " + e.getMessage());
                }

                // 设置边框样式
                switch (borderStyle) {
                    case 0: // 无边框
                        jp.setOpaque(true); // 确保面板是不透明的，以显示背景色
                        jp.setBorder(null);
                        break;
                    case 1: // 简单边框
                        jp.setOpaque(true); // 确保面板是不透明的，以显示背景色
                        jp.setBorder(BorderFactory.createLineBorder(Color.GRAY));
                        break;
                    case 2: // 凸起边框
                        jp.setOpaque(true); // 确保面板是不透明的，以显示背景色
                        jp.setBorder(BorderFactory.createRaisedBevelBorder());
                        break;
                    case 3: // 凹陷边框
                        jp.setOpaque(true); // 确保面板是不透明的，以显示背景色
                        jp.setBorder(BorderFactory.createLoweredBevelBorder());
                        break;
                    case 4: // 蚀刻边框
                        jp.setOpaque(true); // 确保面板是不透明的，以显示背景色
                        jp.setBorder(BorderFactory.createEtchedBorder());
                        break;
                    case 5: // 科技边框
                        // 保存当前背景图片设置状态
                        boolean previousBgImageState = useBackgroundImage;

                        // 关闭背景图片功能
                        useBackgroundImage = false;
                        if (toggleBackgroundImageItem != null) {
                            toggleBackgroundImageItem.setText("启用背景图片");
                        }
                        SettingContext.store(SETTING_CONF, "textbox.background.image.enabled", "false");

                        // 确保面板背景透明，使边框效果正确显示
                        jp.setOpaque(false);
                        // 应用科技边框，传入当前背景颜色
                        jp.setBorder(new com.inputabc.ct.v1.ui.border.TechBorder(backgroundColor));

                        System.out.println("应用科技边框，背景图片已关闭");
                        break;
                    case 6: // 终端边框
                        // 保存当前背景图片设置状态
                        boolean previousBgImageState2 = useBackgroundImage;

                        // 关闭背景图片功能
                        useBackgroundImage = false;
                        if (toggleBackgroundImageItem != null) {
                            toggleBackgroundImageItem.setText("启用背景图片");
                        }
                        SettingContext.store(SETTING_CONF, "textbox.background.image.enabled", "false");

                        // 确保面板背景透明，使边框效果正确显示
                        jp.setOpaque(false);
                        // 应用终端边框，传入当前背景颜色
                        jp.setBorder(new com.inputabc.ct.v1.ui.border.TerminalBorder(backgroundColor));

                        System.out.println("应用终端边框，背景图片已关闭");
                        break;
                    default:
                        jp.setOpaque(true); // 确保面板是不透明的，以显示背景色
                        jp.setBorder(null);
                }

                // 在边框样式改变后，重新应用背景设置
                setScrollPaneBackground();

                // 确保整个UI被刷新
                if (jp instanceof BackgroundPanel) {
                    ((BackgroundPanel) jp).repaint();
                }

                // 刷新整个窗口
                if (jf != null) {
                    jf.repaint();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 加载背景图片
     */
    private void loadBackgroundImage() {
        try {
            Properties p = new Properties();
            File file = new File(SETTING_CONF);
            if (file.exists()) {
                FileInputStream fis = new FileInputStream(file);
                p.load(new InputStreamReader(fis, "UTF-8"));
                fis.close();

                String enabled = p.getProperty("textbox.background.image.enabled", "false");
                useBackgroundImage = Boolean.parseBoolean(enabled);

                // 更新菜单项文本
                if (toggleBackgroundImageItem != null) {
                    toggleBackgroundImageItem.setText(useBackgroundImage ? "禁用背景图片" : "启用背景图片");
                }

                if (useBackgroundImage) {
                    String imagePath = p.getProperty("textbox.background.image");
                    if (imagePath != null && !imagePath.isEmpty()) {
                        // 处理编码问题
                        try {
                            // 尝试直接使用文件路径
                            File imageFile = new File(imagePath);
                            if (!imageFile.exists()) {
                                // 如果直接使用路径无法找到文件，尝试重新编码
                                String decodedPath = new String(imagePath.getBytes("ISO-8859-1"), "UTF-8");
                                imageFile = new File(decodedPath);
                                // 如果重新编码后找到了文件，更新路径
                                if (imageFile.exists()) {
                                    imagePath = decodedPath;
                                    SettingContext.store(SETTING_CONF, "textbox.background.image", decodedPath);
                                }
                            }

                            if (imageFile.exists()) {
                                try {
                                    // 使用ImageIO安全地加载图片
                                    Image img = ImageIO.read(imageFile);
                                    if (img != null) {
                                        backgroundImage = img;
                                        System.out.println("成功加载背景图片: " + imagePath);

                                        // 更新UI
                                        if (jp != null) {
                                            jp.repaint();
                                            if (jf != null) {
                                                jf.repaint();
                                            }
                                        }
                                    } else {
                                        System.err.println("无法加载背景图片: " + imagePath);
                                        useBackgroundImage = false;
                                    }
                                } catch (Exception e) {
                                    System.err.println("加载背景图片时出错: " + e.getMessage());
                                    e.printStackTrace();
                                    useBackgroundImage = false;
                                }
                            } else {
                                System.err.println("背景图片文件不存在: " + imagePath);
                                useBackgroundImage = false;
                            }
                        } catch (Exception e) {
                            System.err.println("处理图片路径编码时出错: " + e.getMessage());
                            e.printStackTrace();
                            useBackgroundImage = false;
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("加载背景图片设置时出错: " + e.getMessage());
            e.printStackTrace();
            useBackgroundImage = false;
        }
    }

    /**
     * 加载翻译设置
     */
    private void loadTranslationSettings() {
        try {
            Properties p = new Properties();
            File file = new File(SETTING_CONF);
            if (file.exists()) {
                p.load(file.toURI().toURL().openStream());

                // 加载翻译方向
                String direction = p.getProperty("textbox.translation.direction", "EN2CN");

                // 加载翻译引擎
                String engine = p.getProperty("textbox.translation.engine", "DEEPSEEK"); // 默认使用DeepSeek

                // 加载API密钥
                loadAPIKeys(p);

                // 如果引擎没有设置，根据API密钥选择默认引擎
                if (engine.isEmpty()) {
                    // 优先选择DeepSeek作为默认引擎
                    engine = "DEEPSEEK";
                    // 如果有其他API密钥则依次选择
                    if (!YoudaoUtils.APP_KEY.isEmpty() && !YoudaoUtils.APP_SECRET.isEmpty()) {
                        engine = "YOUDAO";
                    } else if (!BaiduUtils.APP_ID.isEmpty() && !BaiduUtils.APP_SECRET.isEmpty()) {
                        engine = "BAIDU";
                    } else if (!GoogleUtils.API_KEY.isEmpty()) {
                        engine = "GOOGLE";
                    }
                }

                // 设置翻译方向
                setTranslationDirection(direction);

                // 设置翻译引擎
                setTranslationEngine(engine);
            } else {
                // 默认使用英译中和DeepSeek翻译
                setTranslationDirection("EN2CN");
                setTranslationEngine("DEEPSEEK");
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 出现异常设置默认值
            setTranslationDirection("EN2CN");
            setTranslationEngine("DEEPSEEK");
        }
    }

    /**
     * 加载API密钥设置
     */
    private void loadAPIKeys(Properties p) {
        // 加载有道API密钥
        String youdaoAppKey = p.getProperty("youdao.app_key", "");
        String youdaoAppSecret = p.getProperty("youdao.app_secret", "");
        if (!youdaoAppKey.isEmpty()) {
            YoudaoUtils.APP_KEY = youdaoAppKey;
        }
        if (!youdaoAppSecret.isEmpty()) {
            YoudaoUtils.APP_SECRET = youdaoAppSecret;
        }

        // 加载百度API密钥
        String baiduAppId = p.getProperty("baidu.app_id", "");
        String baiduAppSecret = p.getProperty("baidu.app_secret", "");
        if (!baiduAppId.isEmpty()) {
            BaiduUtils.APP_ID = baiduAppId;
        }
        if (!baiduAppSecret.isEmpty()) {
            BaiduUtils.APP_SECRET = baiduAppSecret;
        }

        // 加载Google API密钥
        String googleApiKey = p.getProperty("google.api_key", "");
        if (!googleApiKey.isEmpty()) {
            GoogleUtils.API_KEY = googleApiKey;
        }
    }

    /**
     * 设置翻译方向
     */
    private void setTranslationDirection(String direction) {
        JMenuItem menuItem = null;

        switch (direction) {
            case "EN2CN":
                menuItem = textBoxTranslationMenuEN2CN;
                break;
            case "JA2CN":
                menuItem = textBoxTranslationMenuJA2CN;
                break;
            case "KR2CN":
                menuItem = textBoxTranslationMenuKR2CN;
                break;
            case "CN2EN":
                menuItem = textBoxTranslationMenuCN2EN;
                break;
            case "CN2JA":
                menuItem = textBoxTranslationMenuCN2JA;
                break;
            case "CN2KR":
                menuItem = textBoxTranslationMenuCN2KR;
                break;
            case "AUTO2CN":
                menuItem = textBoxTranslationMenuAUTO2CN;
                break;
            case "AUTO2EN":
                menuItem = textBoxTranslationMenuAUTO2EN;
                break;
            case "AUTO2JA":
                menuItem = textBoxTranslationMenuAUTO2JA;
                break;
            case "AUTO2KR":
                menuItem = textBoxTranslationMenuAUTO2KR;
                break;
            default:
                menuItem = textBoxTranslationMenuEN2CN;
                break;
        }

        // 设置当前翻译方向菜单项
        if (currentTranslationDirectionMenuItem != null) {
            currentTranslationDirectionMenuItem.setIcon(null);
        }

        menuItem.setIcon((Icon) ContextParams.contextParam.get("menuIcon"));
        currentTranslationDirectionMenuItem = menuItem;

        // 保存设置
        SettingContext.store(SETTING_CONF, "textbox.translation.direction", direction);
    }

    /**
     * 设置翻译引擎
     */
    private void setTranslationEngine(String engine) {
        JMenuItem menuItem = null;

        switch (engine) {
            case "YOUDAO":
                menuItem = textBoxTranslationEngineMenuYoudao;
                break;
            case "BAIDU":
                menuItem = textBoxTranslationEngineMenuBaidu;
                break;
            case "GOOGLE":
                menuItem = textBoxTranslationEngineMenuGoogle;
                break;
            case "DEEPSEEK":
                menuItem = textBoxTranslationEngineMenuDeepSeek;
                break;
            default:
                menuItem = textBoxTranslationEngineMenuDeepSeek; // 默认使用DeepSeek
                break;
        }

        // 设置当前翻译引擎菜单项
        if (currentTranslationEngineMenuItem != null) {
            currentTranslationEngineMenuItem.setIcon(null);
        }

        menuItem.setIcon((Icon) ContextParams.contextParam.get("menuIcon"));
        currentTranslationEngineMenuItem = menuItem;

        // 保存设置
        SettingContext.store(SETTING_CONF, "textbox.translation.engine", engine);
    }

    /**
     * 批量注册事件监听器
     */
    private void event() {
        jf.addWindowListener(new WindowAdapter() {
            @Override
            public void windowOpened(WindowEvent e) {
                Ez.fadeIn(jf, Ez.FADE_FAST);
            }
        });
        // 使窗口可拖动
        bindDragListener(ta, jf);
        // 给右键菜单绑定事件
        new TextBoxPopupMeunListenerHandler(jpm).bindMenuItemListener();

        // 添加外观菜单事件
        addAppearanceMenuListeners();

        ta.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                int i = e.getKeyCode();
                switch (i) {
                    case KeyEvent.VK_LEFT:
                        left = false;
                        break;
                    case KeyEvent.VK_UP:
                        up = false;
                        break;
                    case KeyEvent.VK_DOWN:
                        down = false;
                        break;
                    case KeyEvent.VK_RIGHT:
                        right = false;
                        break;
                    case 61:
                        add = false;
                        break;
                    case 107:
                        add = false;
                        break;
                    case 45:
                        subtract = false;
                        break;
                    case 109:
                        subtract = false;
                        break;
                }
            }

            @Override
            public void keyPressed(KeyEvent e) {
                int i = e.getKeyCode();
                switch (i) {
                    case KeyEvent.VK_LEFT:
                        left = true;
                        break;
                    case KeyEvent.VK_UP:
                        up = true;
                        break;
                    case KeyEvent.VK_DOWN:
                        down = true;
                        break;
                    case KeyEvent.VK_RIGHT:
                        right = true;
                        break;
                    case 61:
                        add = true;
                        break;
                    case 107:
                        add = true;
                        break;
                    case 45:
                        subtract = true;
                        break;
                    case 109:
                        subtract = true;
                        break;
                }
                // System.out.println(e.getKeyCode());
                if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_Z) {
                    ta.setText(ContextParams.contextParam.get("previousText").toString());
                } else if ((e.isAltDown() && add && subtract == false)) {
                    jf.setSize(jf.getWidth() + 20, jf.getHeight() + 20);
                    jf.setLocation(jf.getX() - 10, jf.getY() - 20);
                } else if ((e.isAltDown() && subtract && add == false && left == false && right == false && up == false
                        && down == false)) {
                    jf.setSize(jf.getWidth() - 20, jf.getHeight() - 20);
                    jf.setLocation(jf.getX() + 10, jf.getY() + 20);
                } else if ((e.isControlDown() && add && subtract == false)) {
                    Font font = ta.getFont();
                    ta.setFont(getCommonFontWithSize(font.getSize() + 4));
                    SettingContext.store(SETTING_CONF, "textbox.font.size", String.valueOf(font.getSize() + 4));
                } else if ((e.isControlDown() && subtract && add == false)) {
                    Font font = ta.getFont();
                    ta.setFont(getCommonFontWithSize(font.getSize() - 4));
                    SettingContext.store(SETTING_CONF, "textbox.font.size", String.valueOf(font.getSize() - 4));
                } else if (e.isAltDown() && up && subtract == false) {
                    jf.setSize(jf.getWidth(), jf.getHeight() + 20);
                    jf.setLocation(jf.getX(), jf.getY() - 20);
                } else if (e.isAltDown() && down && subtract == false) {
                    jf.setSize(jf.getWidth(), jf.getHeight() + 20);
                } else if (e.isAltDown() && left && subtract == false) {
                    jf.setSize(jf.getWidth() + 20, jf.getHeight());
                    jf.setLocation(jf.getX() - 20, jf.getY());
                } else if (e.isAltDown() && right && subtract == false) {
                    jf.setSize(jf.getWidth() + 20, jf.getHeight());
                    jf.setLocation(jf.getX(), jf.getY());
                } else if (e.isControlDown() && up && left == false && right == false && down == false) {
                    up();
                } else if (e.isControlDown() && down && left == false && right == false && up == false) {
                    down();
                } else if (e.isControlDown() && left && up == false && down == false && right == false) {
                    left();
                } else if (e.isControlDown() && right && up == false && down == false && left == false) {
                    right();
                } else if (e.getKeyCode() == KeyEvent.VK_F2) {
//                    Map<Integer, Color> bgColorMap = (Map<Integer, Color>) ContextParams.contextParam.get("bgColorMap");
//                    Map<Integer, Color> fgColorMap = (Map<Integer, Color>) ContextParams.contextParam.get("fgColorMap");
//                    int pos = (int) ContextParams.contextParam.get("colorMapPos");
//                    pos = ++pos == 24 ? 0 : pos;
//                    ContextParams.contextParam.put("colorMapPos", pos);
//                    jsp.getViewport().setBackground(bgColorMap.get(pos));
//                    ta.setForeground(fgColorMap.get(pos));
//                    SettingContext.store(SETTING_CONF,"textbox.background.color",bgColorMap.get(pos).getRed()+","+bgColorMap.get(pos).getGreen()+","+bgColorMap.get(pos).getBlue());
//                    SettingContext.store(SETTING_CONF,"textbox.foreground.color",fgColorMap.get(pos).getRed()+","+fgColorMap.get(pos).getGreen()+","+fgColorMap.get(pos).getBlue());
                } else if (e.isControlDown() && up && left && right == false && down == false) {
                    left_up();
                } else if (e.isControlDown() && up && right && left == false && down == false) {
                    right_up();
                } else if (e.isControlDown() && down && left && up == false && right == false) {
                    left_down();
                } else if (e.isControlDown() && down && right && up == false && left == false) {
                    right_down();
                } else if (e.isAltDown() && subtract && add == false && left && right == false && up == false
                        && down == false) {
                    // 从左边缩小窗口
                    jf.setSize(jf.getWidth() - 20, jf.getHeight());
                    jf.setLocation(jf.getX() + 20, jf.getY());
                } else if (e.isAltDown() && subtract && add == false && left == false && right && up == false
                        && down == false) {
                    // 从右边缩小窗口
                    jf.setSize(jf.getWidth() - 20, jf.getHeight());
                    jf.setLocation(jf.getX(), jf.getY());
                } else if (e.isAltDown() && subtract && add == false && left == false && right == false && up
                        && down == false) {
                    // 从上边缩小窗口
                    jf.setSize(jf.getWidth(), jf.getHeight() - 20);
                    jf.setLocation(jf.getX(), jf.getY() + 20);
                } else if (e.isAltDown() && subtract && add == false && left == false && right == false && up == false
                        && down) {
                    // 从下边缩小窗口
                    jf.setSize(jf.getWidth(), jf.getHeight() - 20);
                    jf.setLocation(jf.getX(), jf.getY());
                }
            }
        });
        ta.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON1) {
                    if ("left_top".equals(resizeType)) {
                        resizingBox = true;
                        resizeBoxListenerBinder.mouseDragged(ta, "left_top", jf);
                    } else if ("right_top".equals(resizeType)) {
                        resizingBox = true;
                        resizeBoxListenerBinder.mouseDragged(ta, "right_top", jf);
                    } else if ("left_bottom".equals(resizeType)) {
                        resizingBox = true;
                        resizeBoxListenerBinder.mouseDragged(ta, "left_bottom", jf);
                    } else if ("right_bottom".equals(resizeType)) {
                        resizingBox = true;
                        resizeBoxListenerBinder.mouseDragged(ta, "right_bottom", jf);
                    } else if ("left".equals(resizeType)) {
                        resizingBox = true;
                        resizeBoxListenerBinder.mouseDragged(ta, "left", jf);
                    } else if ("right".equals(resizeType)) {
                        resizingBox = true;
                        resizeBoxListenerBinder.mouseDragged(ta, "right", jf);
                    } else if ("top".equals(resizeType)) {
                        resizingBox = true;
                        resizeBoxListenerBinder.mouseDragged(ta, "top", jf);
                    } else if ("bottom".equals(resizeType)) {
                        resizingBox = true;
                        resizeBoxListenerBinder.mouseDragged(ta, "bottom", jf);
                    }
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON1) {
                    resizeType = null;
                    if (resizingBox) {
                        resizeBoxListenerBinder.unbind(ta, null, textBoxAction, null, null);
                        resizingBox = false;
                    }

                }
            }
        });
        ta.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                if (resizingBox) {
                    return;
                }
                JComponent source = (JComponent) e.getSource();

                if ((e.getX() >= 0 && e.getX() <= 5) && (e.getY() >= 0 && e.getY() <= 5)) {
                    source.setCursor(new Cursor(Cursor.NW_RESIZE_CURSOR));
                    resizeType = "left_top";
                } else if ((e.getX() >= source.getWidth() - 5 && e.getX() <= source.getWidth())
                        && (e.getY() >= 0 && e.getY() <= 5)) {
                    source.setCursor(new Cursor(Cursor.NE_RESIZE_CURSOR));
                    resizeType = "right_top";
                } else if ((e.getX() >= 0 && e.getX() <= 5)
                        && (e.getY() >= source.getHeight() - 5 && e.getY() <= source.getHeight())) {
                    source.setCursor(new Cursor(Cursor.SW_RESIZE_CURSOR));
                    resizeType = "left_bottom";
                } else if ((e.getX() >= source.getWidth() - 5 && e.getX() < source.getWidth())
                        && (e.getY() >= source.getHeight() - 5 && e.getY() <= source.getHeight())) {
                    source.setCursor(new Cursor(Cursor.SE_RESIZE_CURSOR));
                    resizeType = "right_bottom";
                } else if (e.getX() >= 0 && e.getX() <= 5) {
                    source.setCursor(new Cursor(Cursor.W_RESIZE_CURSOR));
                    resizeType = "left";
                } else if (e.getX() >= source.getWidth() - 5 && e.getX() <= source.getWidth()) {
                    source.setCursor(new Cursor(Cursor.W_RESIZE_CURSOR));
                    resizeType = "right";
                } else if (e.getY() >= 0 && e.getY() <= 5) {
                    source.setCursor(new Cursor(Cursor.N_RESIZE_CURSOR));
                    resizeType = "top";
                } else if (e.getY() >= source.getHeight() - 5 && e.getY() <= source.getHeight()) {
                    source.setCursor(new Cursor(Cursor.N_RESIZE_CURSOR));
                    resizeType = "bottom";
                } else {
                    source.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                    resizeType = null;
                }
            }
        });
        jf.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentMoved(ComponentEvent e) {
                Component source = (Component) e.getSource();
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
                double x = source.getLocation().getX();
                double y = source.getLocation().getY();
                if (x > screenSize.getWidth() - source.getWidth()) {
                    source.setLocation((int) (screenSize.getWidth() - source.getWidth()), (int) y);
                } else if (x < 0) {
                    source.setLocation(0, (int) y);
                } else if (y < 0) {
                    source.setLocation((int) x, 0);
                } else if (y > screenSize.getHeight() - source.getHeight()) {
                    source.setLocation((int) x, (int) (screenSize.getHeight() - source.getHeight()));
                }
                Integer preX = (Integer) ContextParams.contextParam.get("preX");
                Integer preY = (Integer) ContextParams.contextParam.get("preY");

                if (preX != null && source.getWidth() == source.getMinimumSize().width) {
                    source.setLocation(preX, source.getY());
                }
                if (preY != null && source.getHeight() == source.getMinimumSize().height) {
                    source.setLocation(source.getX(), preY);
                }
                SettingContext.store(SETTING_CONF, "textbox.location", source.getX() + "," + source.getY());
            }

            @Override
            public void componentResized(ComponentEvent e) {
                Component source = (Component) e.getSource();
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
                int width = source.getWidth();
                int height = source.getHeight();
                if (width > screenSize.getWidth()) {
                    source.setSize((int) screenSize.getWidth(), height);
                } else if (height > screenSize.getHeight()) {
                    source.setSize(width, (int) screenSize.getHeight());
                }
                if (source.getWidth() > source.getMinimumSize().width) {
                    ContextParams.contextParam.remove("preX");
                }
                if (source.getHeight() > source.getMinimumSize().height) {
                    ContextParams.contextParam.remove("preY");
                }
                SettingContext.store(SETTING_CONF, "textbox.location", source.getX() + "," + source.getY());
                SettingContext.store(SETTING_CONF, "textbox.size", source.getWidth() + "x" + source.getHeight());
            }
        });

        // 添加设置菜单项的事件监听
        textBoxSettingsMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 打开设置窗口
                SettingsDialog settingsDialog = new SettingsDialog(jf, TextBox.this);
                settingsDialog.setVisible(true);
            }
        });

        // 添加历史记录菜单项的事件监听
        textBoxHistoryMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 打开历史记录窗口
                if (historyDialog == null) {
                    historyDialog = new TranslationHistoryDialog(jf);
                }
                historyDialog.setVisible(true);
            }
        });

        // 添加帮助菜单项的事件监听
        textBoxHelpMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 打开帮助窗口
                HelpDialog helpDialog = new HelpDialog(jf);
                helpDialog.setVisible(true);
            }
        });

        // 添加关于菜单项的事件监听
        textBoxAboutMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 打开关于窗口
                AboutDialog aboutDialog = new AboutDialog(jf);
                aboutDialog.setVisible(true);
            }
        });

        // 注册翻译方向菜单事件
        textBoxTranslationMenuEN2CN.addActionListener(e -> setTranslationDirection("EN2CN"));
        textBoxTranslationMenuJA2CN.addActionListener(e -> setTranslationDirection("JA2CN"));
        textBoxTranslationMenuKR2CN.addActionListener(e -> setTranslationDirection("KR2CN"));
        textBoxTranslationMenuCN2EN.addActionListener(e -> setTranslationDirection("CN2EN"));
        textBoxTranslationMenuCN2JA.addActionListener(e -> setTranslationDirection("CN2JA"));
        textBoxTranslationMenuCN2KR.addActionListener(e -> setTranslationDirection("CN2KR"));
        textBoxTranslationMenuAUTO2CN.addActionListener(e -> setTranslationDirection("AUTO2CN"));
        textBoxTranslationMenuAUTO2EN.addActionListener(e -> setTranslationDirection("AUTO2EN"));
        textBoxTranslationMenuAUTO2JA.addActionListener(e -> setTranslationDirection("AUTO2JA"));
        textBoxTranslationMenuAUTO2KR.addActionListener(e -> setTranslationDirection("AUTO2KR"));

        // 注册翻译引擎菜单事件
        textBoxTranslationEngineMenuYoudao.addActionListener(e -> setTranslationEngine("YOUDAO"));
        textBoxTranslationEngineMenuBaidu.addActionListener(e -> setTranslationEngine("BAIDU"));
        textBoxTranslationEngineMenuGoogle.addActionListener(e -> setTranslationEngine("GOOGLE"));
        textBoxTranslationEngineMenuDeepSeek.addActionListener(e -> setTranslationEngine("DEEPSEEK"));

        // 点击菜单项后防止界面错乱
        ActionListener preventUiDisorderListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 刷新界面以防止错乱
                SwingUtilities.invokeLater(() -> {
                    jp.revalidate();
                    jp.repaint();
                });
            }
        };

        // 为可能导致界面错乱的菜单项添加监听器
        copyMi.addActionListener(preventUiDisorderListener);
        selectAllMi.addActionListener(preventUiDisorderListener);
        selectAllAndCopyMi.addActionListener(preventUiDisorderListener);
        textBoxRefreshMenu.addActionListener(preventUiDisorderListener);
        textBoxClearMenuItem.addActionListener(preventUiDisorderListener);
        textBoxOpenInputBoxMenuItem.addActionListener(preventUiDisorderListener);
    }

    /**
     * 添加外观菜单事件监听器
     */
    private void addAppearanceMenuListeners() {
        // 背景图片菜单项事件
        backgroundImageItem.addActionListener(e -> {
            JFileChooser fileChooser = new JFileChooser();
            fileChooser.setDialogTitle("选择背景图片");
            fileChooser.setFileFilter(new FileNameExtensionFilter("图片文件", "jpg", "jpeg", "png", "gif"));

            int result = fileChooser.showOpenDialog(jf);
            if (result == JFileChooser.APPROVE_OPTION) {
                File selectedFile = fileChooser.getSelectedFile();
                try {
                    // 读取并设置背景图片
                    loadBackgroundImage(selectedFile.getAbsolutePath());
                } catch (Exception ex) {
                    ex.printStackTrace();
                    JOptionPane.showMessageDialog(jf, "加载图片失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                }
            }
        });

        // 启用/禁用背景图片菜单项事件
        toggleBackgroundImageItem.addActionListener(e -> {
            // 切换背景图片启用状态
            useBackgroundImage = !useBackgroundImage;

            // 更新菜单项文本
            if (useBackgroundImage) {
                toggleBackgroundImageItem.setText("禁用背景图片");

                // 如果已有背景图片但被禁用了，重新启用
                if (backgroundImage != null) {
                    // 重新启用背景图片
                    jp.repaint();
                } else {
                    // 没有背景图片，提示用户选择一个
                    JOptionPane.showMessageDialog(jf, "请选择一个背景图片", "提示", JOptionPane.INFORMATION_MESSAGE);
                    // 触发背景图片菜单项的点击事件
                    backgroundImageItem.doClick();
                }
            } else {
                toggleBackgroundImageItem.setText("启用背景图片");
                // 禁用背景图片，重绘面板
                jp.repaint();
            }

            // 保存设置
            SettingContext.store(SETTING_CONF, "textbox.background.image.enabled", String.valueOf(useBackgroundImage));
        });

        // 背景颜色菜单项事件
        backgroundColorMenuItem.addActionListener(e -> {
            // 获取当前背景颜色
            Color initialColor = jp.getBackground();

            // 显示颜色选择器对话框
            Color selectedColor = JColorChooser.showDialog(jf, "选择背景颜色", initialColor);

            if (selectedColor != null) {
                // 设置新的背景颜色
                jp.setBackground(selectedColor);
                jsp.getViewport().setBackground(selectedColor);

                // 保存设置到配置文件
                String colorStr = selectedColor.getRed() + "," + selectedColor.getGreen() + "," + selectedColor.getBlue();
                SettingContext.store(SETTING_CONF, "textbox.background.color", colorStr);

                // 刷新UI
                SwingUtilities.updateComponentTreeUI(jp);
            }
        });

        // 字体菜单项事件
        fontMenuItem.addActionListener(e -> {
            String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
            JComboBox<String> fontNameComboBox = new JComboBox<>(fontNames);

            // 获取当前字体名称
            String currentFontName = ta.getFont().getFamily();
            fontNameComboBox.setSelectedItem(currentFontName);

            // 字体大小选择
            Integer[] fontSizes = {8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72};
            JComboBox<Integer> fontSizeComboBox = new JComboBox<>(fontSizes);
            fontSizeComboBox.setSelectedItem(ta.getFont().getSize());

            // 字体样式选择
            String[] styles = {"常规", "粗体", "斜体", "粗斜体"};
            JComboBox<String> fontStyleComboBox = new JComboBox<>(styles);

            // 获取当前字体样式
            int currentStyle = ta.getFont().getStyle();
            switch (currentStyle) {
                case Font.BOLD:
                    fontStyleComboBox.setSelectedIndex(1);
                    break;
                case Font.ITALIC:
                    fontStyleComboBox.setSelectedIndex(2);
                    break;
                case Font.BOLD | Font.ITALIC:
                    fontStyleComboBox.setSelectedIndex(3);
                    break;
                default:
                    fontStyleComboBox.setSelectedIndex(0);
                    break;
            }

            // 创建面板
            JPanel panel = new JPanel(new GridLayout(3, 2, 10, 10));
            panel.add(new JLabel("字体:"));
            panel.add(fontNameComboBox);
            panel.add(new JLabel("大小:"));
            panel.add(fontSizeComboBox);
            panel.add(new JLabel("样式:"));
            panel.add(fontStyleComboBox);

            int result = JOptionPane.showConfirmDialog(jf, panel, "选择字体", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
            if (result == JOptionPane.OK_OPTION) {
                String selectedFontName = (String) fontNameComboBox.getSelectedItem();
                int selectedFontSize = (Integer) fontSizeComboBox.getSelectedItem();

                // 获取选择的字体样式
                int selectedFontStyle;
                switch (fontStyleComboBox.getSelectedIndex()) {
                    case 1:
                        selectedFontStyle = Font.BOLD;
                        break;
                    case 2:
                        selectedFontStyle = Font.ITALIC;
                        break;
                    case 3:
                        selectedFontStyle = Font.BOLD | Font.ITALIC;
                        break;
                    default:
                        selectedFontStyle = Font.PLAIN;
                        break;
                }

                // 设置新字体
                setFontWithSettings(selectedFontName, selectedFontSize, selectedFontStyle);

                // 保存设置
                SettingContext.store(SETTING_CONF, "textbox.font.name", selectedFontName);
                SettingContext.store(SETTING_CONF, "textbox.font.size", String.valueOf(selectedFontSize));
                SettingContext.store(SETTING_CONF, "textbox.font.style", String.valueOf(selectedFontStyle));
            }
        });

        // 文字颜色菜单项事件
        textColorMenuItem.addActionListener(e -> {
            // 获取当前文本颜色
            Color initialColor = ta.getForeground();

            // 显示颜色选择器对话框
            Color selectedColor = JColorChooser.showDialog(jf, "选择文字颜色", initialColor);

            if (selectedColor != null) {
                // 设置新的文本颜色
                ta.setForeground(selectedColor);

                // 保存设置到配置文件
                String colorStr = selectedColor.getRed() + "," + selectedColor.getGreen() + "," + selectedColor.getBlue();
                SettingContext.store(SETTING_CONF, "textbox.foreground.color", colorStr);
            }
        });

        // 透明度菜单项事件
        opacityMenuItem.addActionListener(e -> {
            // 当前透明度
            float currentOpacity = jf.getOpacity();

            // 创建滑块用于选择透明度
            JSlider opacitySlider = new JSlider(JSlider.HORIZONTAL, 20, 100, (int) (currentOpacity * 100));
            opacitySlider.setMajorTickSpacing(10);
            opacitySlider.setMinorTickSpacing(5);
            opacitySlider.setPaintTicks(true);
            opacitySlider.setPaintLabels(true);

            JPanel panel = new JPanel(new BorderLayout());
            panel.add(new JLabel("调整透明度："), BorderLayout.NORTH);
            panel.add(opacitySlider, BorderLayout.CENTER);

            // 预览透明度变化
            opacitySlider.addChangeListener(event -> {
                float opacity = opacitySlider.getValue() / 100.0f;
                safelySetOpacity(jf, opacity);
            });

            int result = JOptionPane.showConfirmDialog(jf, panel, "设置透明度", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);

            if (result == JOptionPane.CANCEL_OPTION) {
                // 如果取消，恢复原始透明度
                safelySetOpacity(jf, currentOpacity);
            } else if (result == JOptionPane.OK_OPTION) {
                // 如果确定，保存设置
                float opacity = opacitySlider.getValue() / 100.0f;

                // 确保窗口有正确的透明度设置
                safelySetOpacity(jf, opacity);

                // 保存设置
                SettingContext.store(SETTING_CONF, "textbox.opacity", String.valueOf(opacity));
            }
        });
    }

    /**
     * 根据设置更新字体
     *
     * @param fontName 字体名称
     * @param fontSize 字体大小
     */
    private void setFontWithSettings(String fontName, int fontSize) {
        try {
            // 获取当前字体样式，如果设置过
            int fontStyle = Font.PLAIN;
            Properties p = new Properties();
            File file = new File(SETTING_CONF);
            if (file.exists()) {
                // 使用UTF-8编码读取配置文件
                FileInputStream fis = new FileInputStream(file);
                p.load(new InputStreamReader(fis, "UTF-8"));
                fis.close();

                String fontStyleV = p.getProperty("textbox.font.style");
                if (fontStyleV != null && !fontStyleV.isEmpty()) {
                    try {
                        fontStyle = Integer.parseInt(fontStyleV);
                    } catch (NumberFormatException e) {
                        System.err.println("解析字体样式出错: " + e.getMessage());
                    }
                }
            }

            // 创建新字体
            Font newFont;

            // 检查字体是否在系统中存在
            boolean fontExists = false;
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            String[] fontNames = ge.getAvailableFontFamilyNames();
            for (String name : fontNames) {
                if (name.equals(fontName)) {
                    fontExists = true;
                    break;
                }
            }

            if (fontExists) {
                newFont = new Font(fontName, fontStyle, fontSize);
                System.out.println("设置字体: " + fontName + ", 样式: " + fontStyle + ", 大小: " + fontSize);
            } else {
                System.err.println("字体'" + fontName + "'在系统中不存在，使用默认字体");
                newFont = getCommonFontWithSize(fontSize);
                if (fontStyle != Font.PLAIN) {
                    newFont = newFont.deriveFont(fontStyle);
                }
            }

            // 应用到文本区域
            ta.setFont(newFont);

            // 确保背景图片设置保持不变
            if (jp instanceof BackgroundPanel) {
                ((BackgroundPanel) jp).setUseBackgroundImage(useBackgroundImage);
                ((BackgroundPanel) jp).setBgImage(backgroundImage);
            }

            // 确保文本区域保持透明
            ta.setOpaque(false);

            // 更新UI时不要重新创建面板对象
            ta.revalidate();
            ta.repaint();
            jp.repaint();
            if (jf != null) {
                jf.repaint();
            }
        } catch (Exception e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(jf, "设置字体失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    /**
     * 根据设置更新字体
     *
     * @param fontName  字体名称
     * @param fontSize  字体大小
     * @param fontStyle 字体样式
     */
    private void setFontWithSettings(String fontName, int fontSize, int fontStyle) {
        try {
            // 创建新字体
            Font newFont;

            // 检查字体是否在系统中存在
            boolean fontExists = false;
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            String[] fontNames = ge.getAvailableFontFamilyNames();
            for (String name : fontNames) {
                if (name.equals(fontName)) {
                    fontExists = true;
                    break;
                }
            }

            if (fontExists) {
                newFont = new Font(fontName, fontStyle, fontSize);
                System.out.println("设置字体: " + fontName + ", 样式: " + fontStyle + ", 大小: " + fontSize);
            } else {
                System.err.println("字体'" + fontName + "'在系统中不存在，使用默认字体");
                newFont = getCommonFontWithSize(fontSize);
                if (fontStyle != Font.PLAIN) {
                    newFont = newFont.deriveFont(fontStyle);
                }
            }

            // 应用到文本区域
            ta.setFont(newFont);

            // 确保背景图片设置保持不变
            if (jp instanceof BackgroundPanel) {
                ((BackgroundPanel) jp).setUseBackgroundImage(useBackgroundImage);
                ((BackgroundPanel) jp).setBgImage(backgroundImage);
            }

            // 确保文本区域保持透明
            ta.setOpaque(false);

            // 更新UI时不要重新创建面板对象
            ta.revalidate();
            ta.repaint();
            jp.repaint();
            if (jf != null) {
                jf.repaint();
            }
        } catch (Exception e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(jf, "设置字体失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    /**
     * 绑定拖动事件到组建
     *
     * @param eventSource 事件源
     * @param dragged     被拖动的组件
     */
    private void bindDragListener(final Component eventSource, final Component dragged) {
        final Point origin = new Point();
        final Map<String, Boolean> flag = new Hashtable<String, Boolean>();
        eventSource.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if ((e.getButton() == MouseEvent.BUTTON1 && e.isControlDown()) || e.getButton() == MouseEvent.BUTTON2) {
                    if (e.getButton() == MouseEvent.BUTTON2) {
                        flag.put("clikedButton2", true);
                    }
                    flag.put("dragable", true);
                    origin.x = e.getX();
                    origin.y = e.getY();
                    ContextParams.contextParam.remove("preX");
                    ContextParams.contextParam.remove("preY");
                } else {
                    flag.put("dragable", false);
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON2) {
                    flag.put("clikedButton2", false);
                }
            }
        });
        eventSource.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {

                if (flag.get("dragable") == true && (e.isControlDown() || flag.get("clikedButton2"))) {
                    Point p = dragged.getLocation();
                    dragged.setLocation(p.x + e.getX() - origin.x, p.y + e.getY() - origin.y);
                }
            }
        });
    }

    private void up() {
        jf.setLocation(jf.getX(), jf.getY() - 10);
    }

    private void down() {
        jf.setLocation(jf.getX(), jf.getY() + 10);
    }

    private void left() {
        jf.setLocation(jf.getX() - 10, jf.getY());
    }

    private void right() {
        jf.setLocation(jf.getX() + 10, jf.getY());
    }

    private void left_up() {
        jf.setLocation(jf.getX() - 10, jf.getY() - 10);
    }

    private void right_up() {
        jf.setLocation(jf.getX() + 10, jf.getY() - 10);
    }

    private void left_down() {
        jf.setLocation(jf.getX() - 10, jf.getY() + 10);
    }

    private void right_down() {
        jf.setLocation(jf.getX() + 10, jf.getY() + 10);
    }

    /**
     * 将目标菜单项设置上图标，同时将其父菜单中的其他子菜单项的图标移除
     *
     * @param jmi 准备设置图标的子菜单项
     * @param jm  父菜单
     */
    private void updateMenuIcon(JMenuItem jmi, JMenu jm) {
        jmi.setIcon((Icon) ContextParams.contextParam.get("menuIcon"));
//		Component[] components = jm.getMenuComponents();
//		for(Component c3:components){
//			if(jmi.getName().equals(c3.getName())==false) {
//				if(c3 instanceof JMenuItem) {
//					((JMenuItem) c3).setIcon(null);
//				}
//			}
//		}
    }

    /**
     * 设置窗体大小
     */
    private void setFrameSize() {
        Integer[] size = textBoxSetting.getSize();
        jf.setSize(size[0], size[1]);
    }

    /**
     * 设置文本区域的背景色
     */
    private void setScrollPaneBackground() {
        try {
            Properties p = new Properties();
            File file = new File(SETTING_CONF);
            if (file.exists()) {
                p.load(file.toURI().toURL().openStream());
                String bgColorV = p.getProperty("textbox.background.color");

                if (bgColorV == null || bgColorV.isEmpty()) {
                    bgColorV = "0,0,0";
                }

                String[] colorSplits = bgColorV.split(",");
                int red = Integer.parseInt(colorSplits[0]);
                int green = Integer.parseInt(colorSplits[1]);
                int blue = Integer.parseInt(colorSplits[2]);

                Color backgroundColor = new Color(red, green, blue);

                // 设置背景颜色
                jsp.setOpaque(false);
                jp.setBackground(backgroundColor);

                // 确保使用最新的背景图片和设置
                if (jp instanceof BackgroundPanel) {
                    ((BackgroundPanel) jp).setUseBackgroundImage(useBackgroundImage);
                    ((BackgroundPanel) jp).setBgImage(backgroundImage);
                    jp.repaint();
                }

                // 如果当前使用的是科技边框或终端边框，更新边框的背景颜色
                if (jp.getBorder() instanceof com.inputabc.ct.v1.ui.border.TechBorder) {
                    ((com.inputabc.ct.v1.ui.border.TechBorder) jp.getBorder()).setBackgroundColor(backgroundColor);
                    jp.repaint();
                } else if (jp.getBorder() instanceof com.inputabc.ct.v1.ui.border.TerminalBorder) {
                    ((com.inputabc.ct.v1.ui.border.TerminalBorder) jp.getBorder()).setBackgroundColor(backgroundColor);
                    jp.repaint();
                }

                // 确保视口透明以显示背景
                jsp.getViewport().setOpaque(false);
                ta.setOpaque(false); // 确保文本区域也是透明的
            } else {
                jsp.getViewport().setBackground(Color.BLACK);
            }
        } catch (Exception e) {
            e.printStackTrace();
            jsp.getViewport().setBackground(Color.BLACK);
        }
    }

    /**
     * 设置字体
     */
    private void setFont() {
        try {
            Properties p = new Properties();
            File file = new File(SETTING_CONF);
            if (file.exists()) {
                // 使用UTF-8编码读取配置文件，确保中文字体名称不会出现乱码
                FileInputStream fis = new FileInputStream(file);
                p.load(new InputStreamReader(fis, "UTF-8"));
                fis.close();

                String fontSizeV = p.getProperty("textbox.font.size");
                String fontNameV = p.getProperty("textbox.font.name");
                String fontStyleV = p.getProperty("textbox.font.style");

                int fontSize = 16;
                if (fontSizeV != null && !fontSizeV.isEmpty()) {
                    try {
                        fontSize = Integer.parseInt(fontSizeV);
                    } catch (NumberFormatException e) {
                        System.err.println("解析字体大小出错: " + e.getMessage());
                    }
                }

                int fontStyle = Font.PLAIN;
                if (fontStyleV != null && !fontStyleV.isEmpty()) {
                    try {
                        fontStyle = Integer.parseInt(fontStyleV);
                    } catch (NumberFormatException e) {
                        System.err.println("解析字体样式出错: " + e.getMessage());
                    }
                }

                Font font;
                if (fontNameV != null && !fontNameV.isEmpty()) {
                    // 检查字体是否在系统中存在
                    boolean fontExists = false;
                    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
                    String[] fontNames = ge.getAvailableFontFamilyNames();
                    for (String name : fontNames) {
                        if (name.equals(fontNameV)) {
                            fontExists = true;
                            break;
                        }
                    }

                    if (fontExists) {
                        font = new Font(fontNameV, fontStyle, fontSize);
                        System.out.println("应用字体: " + fontNameV + ", 样式: " + fontStyle + ", 大小: " + fontSize);
                    } else {
                        System.err.println("字体'" + fontNameV + "'在系统中不存在，使用默认字体");
                        font = getCommonFontWithSize(fontSize);
                        if (fontStyle != Font.PLAIN) {
                            font = font.deriveFont(fontStyle);
                        }
                    }
                } else {
                    font = getCommonFontWithSize(fontSize);
                    if (fontStyle != Font.PLAIN) {
                        font = font.deriveFont(fontStyle);
                    }
                }

                ta.setFont(font);
            } else {
                ta.setFont(getCommonFontWithSize(16));
            }
        } catch (Exception e) {
            e.printStackTrace();
            ta.setFont(getCommonFontWithSize(16));
        }
    }

    private Font getCommonFontWithSize(int size) {
        Font font = null;
        try {
            // 使用资源流加载字体文件
            InputStream is = TextBox.class.getResourceAsStream("/icon/SourceHanSansSC-Normal.otf");
            if (is != null) {
                font = Font.createFont(Font.TRUETYPE_FONT, is);
                font = font.deriveFont(Font.PLAIN, size);
                is.close();
            } else {
                System.err.println("找不到字体文件，使用系统默认字体");
                font = new Font(Font.SANS_SERIF, Font.PLAIN, size);
            }
        } catch (Exception e) {
            System.err.println("加载字体出错: " + e.getMessage());
            e.printStackTrace();
            // 使用系统默认字体作为备选
            font = new Font(Font.SANS_SERIF, Font.PLAIN, size);
        }
        return font;
    }

    /**
     * 设置前景色
     */
    private void setTextAreaForeground() {
        try {
            Properties p = new Properties();
            File file = new File(SETTING_CONF);
            if (file.exists()) {
                p.load(file.toURI().toURL().openStream());
                String fgColorV = p.getProperty("textbox.foreground.color");

                if (fgColorV == null || fgColorV.isEmpty()) {
                    // 如果配置文件中没有设置，则使用textBoxSetting
                    Integer[] foreground = textBoxSetting.getForeground();
                    ta.setForeground(new Color(foreground[0], foreground[1], foreground[2]));
                } else {
                    // 使用配置文件中的设置
                    String[] colorSplits = fgColorV.split(",");
                    int red = Integer.parseInt(colorSplits[0]);
                    int green = Integer.parseInt(colorSplits[1]);
                    int blue = Integer.parseInt(colorSplits[2]);

                    Color foregroundColor = new Color(red, green, blue);
                    ta.setForeground(foregroundColor);
                    System.out.println("应用文字颜色: R=" + red + ", G=" + green + ", B=" + blue);
                }
            } else {
                // 配置文件不存在，使用textBoxSetting
                Integer[] foreground = textBoxSetting.getForeground();
                ta.setForeground(new Color(foreground[0], foreground[1], foreground[2]));
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 发生异常时使用默认设置
            Integer[] foreground = textBoxSetting.getForeground();
            ta.setForeground(new Color(foreground[0], foreground[1], foreground[2]));
        }
    }

    /**
     * 设置初始位置
     */
    private void setFrameLocation() {
        Integer[] location = textBoxSetting.getLocation();
        if (location[0] == -1 && location[1] == -1) {
            jf.setLocation((int) (screenSize.getWidth() - jf.getWidth()), (int) (screenSize.getHeight() - jf.getHeight()));
        } else {
            jf.setLocation(location[0], location[1]);
        }

    }

    /**
     * 应用设置
     */
    public void applySettings() {
        try {
            // 保存当前背景图片状态
            boolean currentUseBackgroundImage = useBackgroundImage;
            Image currentBackgroundImage = backgroundImage;

            // 应用字体设置
            setFont();

            // 先加载背景图片
            loadBackgroundImage();

            // 恢复背景图片状态（如果加载失败）
            if (backgroundImage == null && currentBackgroundImage != null) {
                backgroundImage = currentBackgroundImage;
                useBackgroundImage = currentUseBackgroundImage;
            }

            // 应用背景色设置
            setScrollPaneBackground();

            // 应用前景色设置
            setTextAreaForeground();

            // 应用窗体大小
            setFrameSize();

            // 应用边框样式
            setBorderStyle();

            // 应用透明度设置
            try {
                Properties p = new Properties();
                File file = new File(SETTING_CONF);
                if (file.exists()) {
                    // 使用UTF-8编码读取配置文件
                    FileInputStream fis = new FileInputStream(file);
                    p.load(new InputStreamReader(fis, "UTF-8"));
                    fis.close();

                    String opacityStr = p.getProperty("textbox.opacity", "1.0");
                    try {
                        float opacity = Float.parseFloat(opacityStr);
                        // 确保透明度在合理范围内
                        opacity = Math.max(0.2f, Math.min(1.0f, opacity));

                        // 设置窗口为无装饰样式（如果尚未设置）
                        if (!jf.isUndecorated()) {
                            jf.dispose();
                            jf.setUndecorated(true);
                            jf.setVisible(true);
                        }

                        // 应用透明度
                        safelySetOpacity(jf, opacity);

                        System.out.println("应用窗口透明度: " + opacity);
                    } catch (NumberFormatException ex) {
                        System.err.println("解析透明度值出错: " + ex.getMessage());
                        // 使用默认透明度
                        safelySetOpacity(jf, 1.0f);
                    }
                }
            } catch (Exception e) {
                System.err.println("加载透明度设置时出错: " + e.getMessage());
                e.printStackTrace();
                // 使用默认透明度
                safelySetOpacity(jf, 1.0f);
            }

            // 确保视图组件是透明的
            jsp.setOpaque(false);
            jsp.getViewport().setOpaque(false);
            ta.setOpaque(false);

            // 确保背景面板正确设置
            if (jp instanceof BackgroundPanel) {
                ((BackgroundPanel) jp).setUseBackgroundImage(useBackgroundImage);
                ((BackgroundPanel) jp).setBgImage(backgroundImage);
            }

            // 刷新界面
            jp.revalidate();
            jp.repaint();
            jsp.repaint();
            ta.repaint();
            jf.repaint();
        } catch (Exception e) {
            System.err.println("应用设置时出错: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 添加对翻译历史的记录
     */
    public void addTranslationRecord(String sourceText, String targetText,
                                     String translationDirection, String translationEngine) {
        if (historyDialog == null) {
            historyDialog = new TranslationHistoryDialog(jf);
        }

        historyDialog.addTranslationRecord(sourceText, targetText, translationDirection, translationEngine);
    }

    /**
     * 设置背景图片
     */
    public void setBackgroundImage(String path) {
        try {
            if (path != null && !path.isEmpty()) {
                File imageFile = new File(path);
                if (imageFile.exists()) {
                    Image image = ImageIO.read(imageFile);
                    if (image != null) {
                        this.backgroundImage = image;
                        // 保存设置
                        SettingContext.store(SETTING_CONF, "textbox.background.image", path);
                        // 立即更新UI
                        this.repaint();
                    }
                }
            } else {
                // 清除背景图片
                this.backgroundImage = null;
                SettingContext.store(SETTING_CONF, "textbox.background.image", "");
                this.repaint();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        // 绘制背景图片
        if (useBackgroundImage && backgroundImage != null) {
            Graphics2D g2d = (Graphics2D) g.create();
            try {
                g2d.drawImage(backgroundImage, 0, 0, getWidth(), getHeight(), this);
            } finally {
                g2d.dispose();
            }
        }
    }

    /**
     * 加载外观设置
     */
    private void loadAppearanceSettings() {
        try {
            // 尝试从旧的config.properties和新的settings.conf文件加载
            // 优先使用settings.conf
            Properties p = new Properties();
            File file = new File(SETTING_CONF);

            if (file.exists()) {
                FileInputStream fis = new FileInputStream(file);
                p.load(new InputStreamReader(fis, "UTF-8"));
                fis.close();

                // 加载背景图片
                String backgroundImageEnabled = p.getProperty("textbox.background.image.enabled", "false");
                String backgroundImagePath = p.getProperty("textbox.background.image");

                useBackgroundImage = Boolean.parseBoolean(backgroundImageEnabled);

                // 更新菜单项文本
                if (toggleBackgroundImageItem != null) {
                    toggleBackgroundImageItem.setText(useBackgroundImage ? "禁用背景图片" : "启用背景图片");
                }

                if (useBackgroundImage && backgroundImagePath != null && !backgroundImagePath.isEmpty()) {
                    // 处理编码问题
                    try {
                        File imageFile = new File(backgroundImagePath);
                        if (!imageFile.exists()) {
                            // 尝试不同的编码方式
                            String decodedPath = new String(backgroundImagePath.getBytes("ISO-8859-1"), "UTF-8");
                            imageFile = new File(decodedPath);
                            if (imageFile.exists()) {
                                backgroundImagePath = decodedPath;
                                // 更新配置文件中的路径
                                SettingContext.store(SETTING_CONF, "textbox.background.image", decodedPath);
                            }
                        }

                        if (imageFile.exists()) {
                            backgroundImage = ImageIO.read(imageFile);
                        } else {
                            System.err.println("背景图片文件不存在: " + backgroundImagePath);
                            useBackgroundImage = false;
                        }
                    } catch (Exception e) {
                        System.err.println("处理图片路径编码时出错: " + e.getMessage());
                        e.printStackTrace();
                        useBackgroundImage = false;
                    }
                }

                // 加载字体设置
                String fontName = p.getProperty("textbox.font.name");
                String fontSizeStr = p.getProperty("textbox.font.size");

                if (fontName != null && !fontName.isEmpty() && fontSizeStr != null && !fontSizeStr.isEmpty()) {
                    try {
                        int fontSize = Integer.parseInt(fontSizeStr);
                        setFontWithSettings(fontName, fontSize);
                    } catch (NumberFormatException ex) {
                        System.err.println("解析字体大小时出错: " + ex.getMessage());
                    }
                }

                // 加载文本颜色
                String textColorStr = p.getProperty("textbox.foreground.color");
                if (textColorStr != null && !textColorStr.isEmpty()) {
                    try {
                        String[] colorParts = textColorStr.split(",");
                        if (colorParts.length == 3) {
                            int red = Integer.parseInt(colorParts[0]);
                            int green = Integer.parseInt(colorParts[1]);
                            int blue = Integer.parseInt(colorParts[2]);
                            Color textColor = new Color(red, green, blue);
                            ta.setForeground(textColor);
                        }
                    } catch (Exception ex) {
                        System.err.println("解析文本颜色设置时出错: " + ex.getMessage());
                    }
                }

                // 加载透明度设置
                String opacityStr = p.getProperty("textbox.opacity", "1.0");
                try {
                    float opacity = Float.parseFloat(opacityStr);
                    // 确保透明度值在有效范围内
                    opacity = Math.max(0.2f, Math.min(1.0f, opacity));
                    safelySetOpacity(jf, opacity);
                    System.out.println("应用窗口透明度: " + opacity);
                    // 确保设置被正确保存
                    SettingContext.store(SETTING_CONF, "textbox.opacity", String.valueOf(opacity));
                } catch (NumberFormatException ex) {
                    System.err.println("解析透明度设置时出错: " + ex.getMessage());
                    // 使用默认透明度
                    safelySetOpacity(jf, 1.0f);
                    SettingContext.store(SETTING_CONF, "textbox.opacity", "1.0");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 加载背景图片
     *
     * @param path 图片路径
     */
    private void loadBackgroundImage(String path) {
        try {
            if (path != null && !path.isEmpty()) {
                // 处理编码问题
                File imageFile = new File(path);
                if (!imageFile.exists()) {
                    // 尝试不同的编码方式
                    String decodedPath = new String(path.getBytes("ISO-8859-1"), "UTF-8");
                    imageFile = new File(decodedPath);
                    if (imageFile.exists()) {
                        path = decodedPath;
                    }
                }

                if (imageFile.exists()) {
                    try {
                        System.out.println("尝试加载背景图片: " + path);
                        // 使用ImageIO安全地加载图片
                        Image img = ImageIO.read(imageFile);
                        if (img != null) {
                            backgroundImage = img;
                            // 标记图片已启用
                            useBackgroundImage = true;
                            // 保存设置
                            SettingContext.store(SETTING_CONF, "textbox.background.image", path);
                            SettingContext.store(SETTING_CONF, "textbox.background.image.enabled", "true");

                            System.out.println("成功加载并设置背景图片: " + path);

                            // 更新菜单项文本
                            if (toggleBackgroundImageItem != null) {
                                toggleBackgroundImageItem.setText("禁用背景图片");
                            }

                            // 更新UI
                            if (jp != null) {
                                // 重新设置背景颜色，这将重新创建自定义面板
                                setScrollPaneBackground();
                                jp.repaint();
                                if (jf != null) {
                                    jf.repaint();
                                }
                            }
                        } else {
                            System.err.println("无法加载背景图片: " + path);
                            JOptionPane.showMessageDialog(jf, "无法加载背景图片: " + path, "错误", JOptionPane.ERROR_MESSAGE);
                        }
                    } catch (Exception e) {
                        System.err.println("加载背景图片时出错: " + e.getMessage());
                        e.printStackTrace();
                        JOptionPane.showMessageDialog(jf, "加载图片失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                    }
                } else {
                    System.err.println("背景图片文件不存在: " + path);
                    JOptionPane.showMessageDialog(jf, "图片文件不存在: " + path, "错误", JOptionPane.ERROR_MESSAGE);
                }
            } else {
                // 清除背景图片
                backgroundImage = null;
                useBackgroundImage = false;
                SettingContext.store(SETTING_CONF, "textbox.background.image", "");
                SettingContext.store(SETTING_CONF, "textbox.background.image.enabled", "false");

                // 更新菜单项文本
                if (toggleBackgroundImageItem != null) {
                    toggleBackgroundImageItem.setText("启用背景图片");
                }

                if (jp != null) {
                    setScrollPaneBackground();
                    jp.repaint();
                    if (jf != null) {
                        jf.repaint();
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("处理背景图片路径时出错: " + e.getMessage());
            e.printStackTrace();
            JOptionPane.showMessageDialog(jf, "处理图片路径时出错: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    /**
     * 安全地设置窗口透明度
     *
     * @param frame   要设置透明度的窗口
     * @param opacity 透明度值（0.2到1.0之间）
     */
    public void safelySetOpacity(JFrame frame, float opacity) {
        try {
            // 设置透明度前，需要确保窗口是未装饰的
            boolean wasDecorated = frame.isUndecorated();
            if (!wasDecorated) {
                // 如果窗口是装饰的，无法直接设置透明度
                System.out.println("无法设置透明度：窗口是装饰的");
                return;
            }
            
            // 使用标准JDK API设置透明度
            opacity = Math.max(0.2f, Math.min(1.0f, opacity));
            frame.setOpacity(opacity);
        } catch (Exception e) {
            System.err.println("设置透明度时出错: " + e.getMessage());
            e.printStackTrace();
        }
    }

    // 自定义支持背景图片的面板类
    private class BackgroundPanel extends JPanel {
        private boolean localUseBackgroundImage = false;
        private Image localBackgroundImage = null;

        public BackgroundPanel() {
            super();
            setOpaque(true); // 面板本身是不透明的
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            // 检查当前边框类型，如果是科技边框或终端边框，不绘制背景图片
            boolean isSpecialBorder = false;
            if (this.getBorder() instanceof com.inputabc.ct.v1.ui.border.TechBorder ||
                this.getBorder() instanceof com.inputabc.ct.v1.ui.border.TerminalBorder) {
                isSpecialBorder = true;
            }

            // 只有在不是特殊边框且背景图片设置为启用时才绘制背景图片
            if (!isSpecialBorder && localUseBackgroundImage && localBackgroundImage != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                try {
                    g2d.drawImage(localBackgroundImage, 0, 0, getWidth(), getHeight(), this);
                } finally {
                    g2d.dispose();
                }
            }
        }

        // 设置背景图片
        public void setBgImage(Image image) {
            this.localBackgroundImage = image;
            repaint();
        }

        // 设置是否使用背景图片
        public void setUseBackgroundImage(boolean use) {
            this.localUseBackgroundImage = use;
            repaint();
        }
    }

    /**
     * 获取主窗口
     *
     * @return JFrame实例
     */
    public JFrame getJFrame() {
        return jf;
    }
}
